package com.open.capacity.user.controller;

import java.io.OutputStream;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import com.open.capacity.user.config.SystemConfigProperties;
import com.open.capacity.user.excel.UserExcel;
import com.open.capacity.user.model.SysUserHistory;
import com.open.capacity.user.model.SysUserHistoryDto;
import com.open.capacity.user.service.SysUserRelationService;
import com.open.capacity.user.vo.SysUserVo;
import com.open.capacity.utils.DateUtil;
import com.open.capacity.utils.encrypt.Md5Utils;
import com.open.capacity.vo.MapVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import com.open.capacity.annotation.log.LogAnnotation;
import com.open.capacity.commons.PageResult;
import com.open.capacity.commons.Result;
import com.open.capacity.model.system.LoginAppUser;
import com.open.capacity.model.system.SysUser;
import com.open.capacity.user.service.SysUserService;
import com.open.capacity.utils.SysUserUtil;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author 作者 ftquan E-mail: 464725602@qq.com
 * @version 创建时间：2017年11月12日 上午22:57:51
 * 用户
 */
@Slf4j
@RestController
@Api(tags = "用户模块api")
public class SysUserController {

    @Autowired
    private SysUserService userService;

    @Autowired
    private SysUserRelationService relationService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private SystemConfigProperties configProperties;

    /**
     * 当前登录用户 LoginAppUser
     *
     * @return
     */
    @ApiOperation(value = "根据access_token当前登录用户")
    @GetMapping("/users/current")
    public LoginAppUser getLoginAppUser() {
        LoginAppUser loginUser = null;
        try {
            loginUser = SysUserUtil.getLoginAppUser();
        } catch (Exception e) {
            log.error(e.toString());
            log.error("获取登陆用户失败:{}", e);
        }

        return loginUser;
    }

    @GetMapping(value = "/users-anon/login", params = "username")
    @ApiOperation(value = "根据用户名查询用户")
    public LoginAppUser findByUsername(String username) {
        return userService.findByUsername(username);
    }

    @PreAuthorize("hasAuthority('user:get/users/{id}')")
    @GetMapping("/users/{id}/getHeadImg")
    public Result getUserHeadImg(@PathVariable(value = "id") String userId) {
        SysUser user = userService.findById(userId);
        if (user != null) {
            return Result.succeed(user.getHeadUrl());
        }
        return Result.failed("找不到用户");
    }


    /**
     * 查询用户map
     *
     * @param ver
     * @return
     */
    @PreAuthorize("hasAuthority('user:get/users')")
    @ApiOperation(value = "查询用户map")
    @GetMapping("/users/map")
    public Result<MapVo> mapUsers(@RequestParam(value = "ver", required = false) String ver) {
        Map<String, SysUserVo> userMaps = userService.getMap();
        String md5 = JSONObject.toJSONString(userMaps);
        if (md5.equals(ver)) {
            return Result.succeed("NO UPDATE");
        }
        MapVo<Map<String, SysUserVo>> vo = new MapVo();
        vo.setData(userMaps);
        vo.setVer(Md5Utils.hash(md5));
        return Result.succeed(vo);
    }

    @PreAuthorize("hasAuthority('user:get/users/{id}')")
    @GetMapping("/users/{id}")
    public SysUser findUserById(@PathVariable(value = "id") String id) {
        return userService.findById(id);
    }

    @GetMapping("/users/getName")
    public Result getName(@RequestParam(value = "keyValue") String keyValue) {
        SysUser user = userService.findById(keyValue);
        return Result.succeed(user == null ? "" : user.getRealName(), "获取成功！");
    }

    @GetMapping("/users/getPostname")
    public Result getPostname(@RequestParam(value = "keyValue") String keyValue) {
        String postNames = relationService.getPostNames(keyValue);
        return Result.succeed(postNames, "获取成功！");
    }

    @GetMapping("/users/getNames")
    public Result getNames(@RequestParam(value = "keyValue") String keyValue) {
        String[] idArray = keyValue.split(",");
        String nameStr = "";
        for (String userId : idArray) {
            SysUser user = userService.findById(userId);
            if (user != null) {
                if (StringUtils.isEmpty(nameStr)) {
                    nameStr += (user.getRealName());
                } else {
                    nameStr += (", " + user.getRealName());
                }
            }
        }
        return Result.succeed(nameStr, "success");
    }


    @PreAuthorize("hasAuthority('user:get/users/{id}')")
    @GetMapping("/users/findUserByIds")
    public Result<List<String>> findUserByIds(@RequestParam String keyValue) {
        String[] idArray = keyValue.split(",");
        List<String> userList = new ArrayList<>();
        for (String userId : idArray) {
            userList.add(userService.findById(userId).getRealName());
        }
        return Result.succeed(userList);
    }


    /**
     * 修改用户
     *
     * @param sysUser
     */
    @PreAuthorize("hasAuthority('user:put/users/me')")
    @PutMapping("/users")
    @LogAnnotation(module = "用户", name = "更新")
    public void updateSysUser(@RequestBody SysUser sysUser) {
        userService.updateSysUser(sysUser);
    }


    /**
     * 用户查询
     * http://192.168.3.2:7000/users?access_token=3b45d059-601b-4c63-85f9-9d77128ee94d&start=0&length=10
     *
     * @param params
     * @return
     */
    @PreAuthorize("hasAuthority('user:get/users')")
    @ApiOperation(value = "用户分页查询列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "分页起始位置", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "limit", value = "分页结束位置", required = true, dataType = "Integer")
    })
    @GetMapping("/users")
    public PageResult<SysUser> findUsers(@RequestParam Map<String, Object> params) {
        return userService.pageUsers(params);
    }

    /**
     * 用户查询
     *
     * @param companyId
     * @param departmentId
     * @param keyword
     * @return
     */
    @PreAuthorize("hasAuthority('user:get/users')")
    @ApiOperation(value = "用户查询列表")
    @GetMapping("/users/list")
    public Result<List<SysUser>> listUsers(@RequestParam(value = "companyId", required = false) String companyId, @RequestParam(value = "departmentId", required = false) String departmentId, @RequestParam(value = "keyword", required = false) String keyword, @RequestParam(value = "simpleSpelling", required = false) String simpleSpelling) {
        Map<String, Object> params = new HashMap<>();
        params.put("companyId", companyId);
        params.put("departmentId", departmentId);
        params.put("keyword", keyword);
        params.put("simpleSpelling", simpleSpelling);
        List<SysUser> list = userService.findUsers(params);
        return Result.succeed(list);
    }

    /**
     * 用户晋升记录
     */
    @PreAuthorize("hasAuthority('user:get/users')")
    @GetMapping("/users/history")
    public Result<List<SysUserHistory>> findUserHistory(String userid) {
        List<SysUserHistory> histories = userService.findUserHistory(userid);
        return Result.succeed(histories);
    }

    /**
     * 设置用户晋升记录
     */
    @PreAuthorize("hasAuthority('user:get/users')")
    @GetMapping("/users/historys")
    public Result<List<SysUserHistoryDto>> findUserHistorys(String userids) {
        List<SysUserHistoryDto> histories = userService.findUserHistorys(userids);
        return Result.succeed(histories);
    }


    @PreAuthorize("hasAuthority('user:get/users')")
    @ApiOperation(value = "判断人员name是否存在")
    @GetMapping("/users/existsName")
    public Result existsName(@RequestParam(value = "userName") String userName) {
        LoginAppUser user = userService.findByUsername(userName);
        return Result.succeed(user != null);
    }

    /**
     * 定期更新密码
     */
    @GetMapping(value = "/users/validateModifyPassword")
    public Result validateModifyPassword() {
        LoginAppUser sysUser = SysUserUtil.getLoginAppUser();
        if (sysUser.getId().equals("1")) {
            return Result.succeed("success");
        }
        Integer resetPasswordEnabled = configProperties.getResetPasswordEnabled();
        if (resetPasswordEnabled != 1) {
            return Result.succeed("success");
        }
        Integer resetPasswordPeriod = configProperties.getResetPasswordPeriod();
        long diffDay = DateUtil.dateDiff(sysUser.getUpdateTime(), new Date(), "d");
        if (diffDay >= resetPasswordPeriod) {
            return Result.failed("请及时更新密码");
        }
        return Result.succeed("success");
    }

    /**
     * 校验密码
     */
    @GetMapping(value = "/users/validatePassword")
    public Result validatePassword(@RequestParam(value = "password") String password) {
        LoginAppUser sysUser = SysUserUtil.getLoginAppUser();
        if (StringUtils.isBlank(password)) {
            throw new IllegalArgumentException("密码不能为空");
        }
        if (sysUser.getId().equals("1")) {
            return Result.failed("超级管理员不给予修改");
        }
        if (!passwordEncoder.matches(password, sysUser.getPassword())) {
            return Result.failed("密码错误");
        } else {
            return Result.succeed("校验成功");
        }
    }

    /**
     * 修改密码
     *
     * @param sysUser
     */
    @PostMapping(value = "/users/password")
    @PreAuthorize("hasAuthority('user:put/users/password')")
    @LogAnnotation(module = "用户", name = "修改密码")
    public Result updatePassword(@RequestBody SysUser sysUser) {
        if (StringUtils.isBlank(sysUser.getOldPassword())) {
            throw new IllegalArgumentException("旧密码不能为空");
        }
        if (StringUtils.isBlank(sysUser.getNewPassword())) {
            throw new IllegalArgumentException("新密码不能为空");
        }

        if (sysUser.getId().equals("1")) {
            return Result.failed("超级管理员不给予修改");
        }

        return userService.updatePassword(sysUser.getId(), sysUser.getOldPassword(), sysUser.getNewPassword());
    }


    /**
     * 更新用户状态
     *
     * @param id
     * @author gitgeek
     */
    @PreAuthorize("hasAuthority('user:post/users/{id}/updateStatus' )")
    @PostMapping(value = "/users/{id}/updateStatus")
    @LogAnnotation(module = "用户", name = "更新状态")
    public Result updateStatus(@PathVariable(value = "id") String id, Integer status) {
        if (id.equals("1")) {
            return Result.failed("超级管理员不允许禁用");
        }
        userService.updateStatus(id, status);
        return Result.succeed(null, "更新成功");
    }

    /**
     * 更新用户头像
     *
     * @param id
     */
    @PreAuthorize("hasAuthority('user:post/users/{id}/updateHeadUrl' )")
    @PostMapping(value = "/users/{id}/updateHeadUrl")
    @LogAnnotation(module = "用户", name = "更新头像")
    public Result updateHeaderUrl(@PathVariable(value = "id") String id, String url) {
        userService.updateHeadUrl(id, url);
        return Result.succeed(null, "更新成功");
    }

    /**
     * 给用户重置密码
     *
     * @param id
     */
    @PreAuthorize("hasAuthority('user:post/users/{id}/resetPassword' )")
    @PostMapping(value = "/users/{id}/resetPassword")
    @LogAnnotation(module = "用户", name = "重置密码")
    public Result resetPassword(@PathVariable(value = "id") String id) {
        if (id.equals("1")) {
            return Result.failed("超级管理员不给予修改");
        }
        return userService.updatePassword(id, null, StringUtils.isEmpty(configProperties.getDefaultPassword()) ? "123456" : configProperties.getDefaultPassword());
    }


    /**
     * 获取用户签名
     */
    @PreAuthorize("hasAuthority('user:post/users/{id}/signature' )")
    @GetMapping(value = "/users/{id}/getSignature")
    public Result getSignature(@PathVariable(value = "id") String id) {
        LoginAppUser sysUser = SysUserUtil.getLoginAppUser();
        return Result.succeed(userService.findSignature(id), "获取成功");
    }

    /**
     * 用户上传签名图片
     *
     * @param id
     */
    @PreAuthorize("hasAuthority('user:post/users/{id}/signature' )")
    @PostMapping(value = "/users/{id}/signature")
    @LogAnnotation(module = "用户", name = "上传签名图片")
    public Result signature(@PathVariable(value = "id") String id, String signature) {
        return userService.updateSignature(id, signature);
    }

    /**
     * 保存银行账号
     *
     * @param sysUsers
     * @return
     */
    @PostMapping("/users/saveBankAccount")
    @LogAnnotation(module = "用户", name = "设置银行账号")
    public Result saveBankAccount(@RequestBody List<SysUser> sysUsers) {
        return userService.saveBankAccount(sysUsers);
    }

    /**
     * 新增or更新
     *
     * @param sysUser
     * @return
     */
    @PostMapping("/users/saveOrUpdate")
    @PreAuthorize("hasAnyAuthority('user:post/users/saveOrUpdate')")
    @LogAnnotation(module = "用户", name = "更新")
    public Result saveOrUpdate(@RequestBody SysUser sysUser, String keyValue) {
        return userService.saveOrUpdate(sysUser, keyValue);
    }

    /**
     * 新增晋升记录
     *
     * @param history
     * @return
     */
    @PostMapping("/users/saveHistory")
    @LogAnnotation(module = "用户", name = "新增晋升记录")
    public Result saveHistory(@RequestBody SysUserHistory history) {
        return userService.saveHistory(history);
    }

    /**
     * 新增晋升记录
     *
     * @param historys
     * @return
     */
    @PostMapping("/users/saveHistorys")
    public Result saveHistorys(@RequestBody List<SysUserHistoryDto> historys) {
        return userService.saveHistorys(historys);
    }


    /**
     * 删除人员
     * delete /users/1
     *
     * @param id
     */
    @PreAuthorize("hasAuthority('user:delete/users/{id}')")
    @ApiOperation(value = "删除人员")
    @DeleteMapping("/users/{id}")
    @LogAnnotation(module = "用户", name = "删除")
    public Result delete(@PathVariable(value = "id") String id) {
        try {
            userService.delete(id);
            return Result.succeed("操作成功");
        } catch (Exception e) {
            log.error(e.toString());

            return Result.failed("操作失败");
        }
    }


    /**
     * 删除人员晋升记录
     * delete /users/history/1
     *
     * @param id
     */
    @PreAuthorize("hasAuthority('user:delete/users/{id}')")
    @ApiOperation(value = "删除人员")
    @DeleteMapping("/users/history/{id}")
    @LogAnnotation(module = "用户", name = "删除晋升记录")
    public Result deleteHistory(@PathVariable(value = "id") String id) {
        try {
            userService.deleteHistory(id);
            return Result.succeed("操作成功");
        } catch (Exception e) {
            log.error(e.toString());

            return Result.failed("操作失败");
        }
    }

    /**
     * 导入excel
     */
    @PostMapping("/users/importExcel")
    @PreAuthorize("hasAuthority('user:post/users/import')")
    public Result importExcel(@RequestParam("file") MultipartFile multipartFile) throws Exception {
        int count = userService.importExcel(multipartFile);
        return Result.succeed(count, "导入成功");
    }

    /**
     * 导入excel
     */
    @PostMapping("/users/importBankAccount")
    @PreAuthorize("hasAuthority('user:post/users/import')")
    @LogAnnotation(module = "用户", name = "导入银行账号")
    public Result importBankAccount(@RequestParam("file") MultipartFile multipartFile) throws Exception {
        int count = userService.importBankAccount(multipartFile);
        return Result.succeed(count, "导入成功");
    }

    /**
     * 导出数据
     *
     * @return
     */
    @GetMapping("/users/exportUser")
    @PreAuthorize("hasAuthority('user:post/users/exportUser')")
    public void exportUser(@RequestParam Map<String, Object> params, HttpServletRequest request, HttpServletResponse response) {
        List<UserExcel> result = userService.findAllUsers(params);

//        if (!CollectionUtils.isEmpty(result)) {
//            result.forEach(item -> {
//                if (item.getSex() != null && item.getSex().equals(1)) {
//                    item.setSexStr("男");
//                } else if (item.getSex() != null && item.getSex().equals(0)) {
//                    item.setSexStr("女");
//                }
//            });
//        }
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-disposition", "attachment;filename=users.xls");
        OutputStream ouputStream = null;
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(null, "用户"),
                UserExcel.class, result);
        try {
            ouputStream = response.getOutputStream();
            workbook.write(ouputStream);
        } catch (Exception e) {
            log.error(e.toString());
            throw new RuntimeException("系统异常");
        } finally {
            try {
                if (ouputStream != null) {
                    ouputStream.flush();
                    ouputStream.close();
                }
            } catch (Exception e) {
                log.error(e.toString());
                throw new RuntimeException("系统异常");
            }
        }
    }


}
